/**
 * 抽象工厂模式
 */

//  工厂方法模式可以进一步优化，提取出工厂接口

interface IFactory {
    create(): Fruit;
}
class Fruit {}
class Apple extends Fruit {}
class Pear extends Fruit {}

class AppleFactory implements IFactory {
    create() {
        return new Apple();
    }
}
class PearFactory implements IFactory {
    create() {
        return new Pear();
    }
}

const appleFactory: IFactory = new AppleFactory();
const apple = appleFactory.create();
const pearFactory: IFactory = new PearFactory();
const pear = pearFactory.create();

// 抽象工厂模式主要用于替换一系列方法
// 例如将程序中的 SQL Server 数据库整个替换为 Access 数据库

// 抽象工厂模式很好的发挥了开闭原则、依赖倒置原则，但缺点是:
// 抽象工厂模式太重了，如果 IFactory 接口需要新增功能，则会影响到所有的具体工厂类。
//        使用抽象工厂模式，替换具体工厂时只需更改一行代码，但要新增抽象方法则需要修改所有的具体工厂类。
//        所以抽象工厂模式适用于增加同类工厂这样的横向扩展需求，不适合新增功能这样的纵向扩展。
